package org.lgiavedoni.android.franq.service.question;

import org.lgiavedoni.android.franq.core.cron.CronTask;
import org.lgiavedoni.android.franq.core.cron.RepetibleCron;
import org.lgiavedoni.android.franq.core.message.MessageInterceptor;
import org.lgiavedoni.android.franq.core.question.Question;
import org.lgiavedoni.android.franq.core.question.QuestionMessageInterceptor;
import org.lgiavedoni.android.franq.core.service.Service;
import org.lgiavedoni.android.franq.core.speak.CommonPhraseHelper;
import org.lgiavedoni.android.franq.service.communication.CommunicationService;
import org.lgiavedoni.android.franq.service.config.ConfigService;
import org.lgiavedoni.android.franq.service.config.ConfigService.ConfigKey;
import org.lgiavedoni.android.franq.service.log.Logger;
import org.lgiavedoni.android.franq.service.question.dao.QuestionDAO;
import org.lgiavedoni.android.franq.util.date.DateUtil;
import org.lgiavedoni.android.franq.util.thread.ThreadUtil;

public class QuestionService extends Service {

	public static final QuestionService inst = new QuestionService();
	private final static QuestionDAO questionDAO = QuestionDAO.inst;

	private QuestionService() {
	}

	@Override
	public String getServiceName() {
		return "questions";
	}

	@Override
	protected void startInternal() {

	}

	@Override
	protected void stopInternal() {

	}

	public Question<?> askNowAndWait(Question<?> question) {
		return askNowAndWait(question, false);
	}

	public Question<?> askNowAndWait(Question<?> question, boolean saveQuestion) {
		while (true) {
			if (!CommunicationService.inst.isBusy()) {
				MessageInterceptor messageInterceptor = getNewMessageInterceptor();
				messageInterceptor.setQuestion(question);
				CommunicationService.inst.setMessageInterceptor(messageInterceptor);

				question.ask();

				// The questions was Discarded
				if (question.isDiscarded()) {
					CommunicationService.inst.sendMessage(CommonPhraseHelper.DISCARDED_QUESTION);
				}
				// remove the question
				CommunicationService.inst.clearMessageInterceptor();

				if (question.isSaved())
					questionDAO.update(question);
				else if (saveQuestion) {
					questionDAO.add(question);
				}

				return question;
			}
			// Waiting for place in Communication Service
			ThreadUtil.sleep(5000, "Waiting for a place in the Communication Service");
		}
	}

	public void askNow(final Question<?> question, final boolean saveQuestion) {
		new Thread() {
			@Override
			public void run() {
				askNowAndWait(question, saveQuestion);
			}
		}.start();
	}

	public MessageInterceptor getNewMessageInterceptor() {
		return new QuestionMessageInterceptor();
	}

	public synchronized void addNewQuestion(final Question question) {
		if (!questionDAO.getAll().contains(question)/*
													 * CollectionUtils.isEmpty(
													 * questionDAO
													 * .getAllByExample
													 * (question))
													 */) {
			Logger.inst.debug("Adding a new question [" + question + "]");
			questionDAO.add(question);
		} else {
			Logger.inst.debug("Questions Discarded [" + question + "]. Already existe");
		}
	}

	static class MyCron extends CronTask implements RepetibleCron {

		@Override
		public void run() {
			// No questions during the night
			if (DateUtil.isHourBetween(0, 7)) {
				final Question nextQuestion = questionDAO.getNextQuestion();
				if (nextQuestion != null) {
					inst.askNowAndWait(nextQuestion);
				}
			}
		}

		@Override
		public long getDelay() {
			return DateUtil.getMillisecondsOfMins(2);
		}

		@Override
		public long getPeriod() {
			return ConfigService.inst.getRandomValueAsLong(ConfigKey.QUESTION_SERVICE_SLEEP);
		}
	}

	@Override
	protected void _run() {
		// TODO Auto-generated method stub

	}
}
